package org.sensmon.gui;

import javax.swing.JPanel;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import javax.swing.JComboBox;
import java.awt.Insets;
import javax.swing.JSpinner;
import javax.swing.JSlider;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.ScrollPaneConstants;
import javax.swing.JButton;
import javax.swing.border.LineBorder;

import org.extdev.device.ltr.LTR11Channel;
import org.extdev.device.ltr.LTR11InputMode;
import org.extdev.device.ltr.LTR11Scale;
import org.extdev.device.ltr.LTR11StartADCMode;
import org.extdev.device.ltr.LTR11VirtualChannelsMode;
import org.extdev.device.ltr.LTRCrate;
import org.extdev.libraries.ltr.LTR11APIConstants;
import org.extdev.libraries.ltr.LTRAPIConstants;
import org.sensmon.core.Inicilizer;

import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.LinkedList;
import java.util.List;

public class LTR11Pane extends JPanel {

	private static final long serialVersionUID = 1L;
	
	private final JSlider pointsCountSlider;
	private final DefaultListModel<LTR11Channel> listModel;

	private JComboBox<LTRCrate> cratesSNComboBox;

	private JComboBox<Short> slotNoComboBox;

	private JComboBox<LTR11StartADCMode> startADCModeComboBox;

	private JComboBox<LTR11InputMode> inputModeComboBox;

	private JSpinner pointsCountSpinner;

	private JSpinner channelSpinner;

	private JComboBox<LTR11VirtualChannelsMode> channelModeComboBox;

	private JComboBox<LTR11Scale> channelScaleComboBox;

	private JButton btnAddChannel;

	private JButton btnRemoveChannel;

	/**
	 * Create the panel.
	 */
	public LTR11Pane() {
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{0, 74, 0};
		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0};
		gridBagLayout.columnWeights = new double[]{1.0, 1.0, 1.0};
		gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
		setLayout(gridBagLayout);
		
		JLabel lblCrateSerialNumber = new JLabel("Crate serial number:");
		GridBagConstraints gbc_lblCrateSerialNumber = new GridBagConstraints();
		gbc_lblCrateSerialNumber.insets = new Insets(0, 0, 5, 5);
		gbc_lblCrateSerialNumber.anchor = GridBagConstraints.EAST;
		gbc_lblCrateSerialNumber.gridx = 0;
		gbc_lblCrateSerialNumber.gridy = 0;
		add(lblCrateSerialNumber, gbc_lblCrateSerialNumber);
		
		cratesSNComboBox = new JComboBox<LTRCrate>(/*Inicilizer.getCrates().toArray(new LTRCrate[Inicilizer.getCrates().size()])*/);
		GridBagConstraints gbc_cratesSNComboBox = new GridBagConstraints();
		gbc_cratesSNComboBox.gridwidth = 2;
		gbc_cratesSNComboBox.insets = new Insets(0, 0, 5, 0);
		gbc_cratesSNComboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_cratesSNComboBox.gridx = 1;
		gbc_cratesSNComboBox.gridy = 0;
		add(cratesSNComboBox, gbc_cratesSNComboBox);
		
		JLabel lblSlot = new JLabel("Slot number:");
		GridBagConstraints gbc_lblSlot = new GridBagConstraints();
		gbc_lblSlot.anchor = GridBagConstraints.EAST;
		gbc_lblSlot.insets = new Insets(0, 0, 5, 5);
		gbc_lblSlot.gridx = 0;
		gbc_lblSlot.gridy = 1;
		add(lblSlot, gbc_lblSlot);
		
		slotNoComboBox = new JComboBox<Short>();
		GridBagConstraints gbc_slotNoComboBox = new GridBagConstraints();
		gbc_slotNoComboBox.gridwidth = 2;
		gbc_slotNoComboBox.insets = new Insets(0, 0, 5, 0);
		gbc_slotNoComboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_slotNoComboBox.gridx = 1;
		gbc_slotNoComboBox.gridy = 1;
		add(slotNoComboBox, gbc_slotNoComboBox);
		if (cratesSNComboBox.getModel().getSize() > 0) {
			cratesSNComboBox.setSelectedIndex(0);
		}
		
		JLabel lblStartAdcMode = new JLabel("Start ADC mode:");
		GridBagConstraints gbc_lblStartAdcMode = new GridBagConstraints();
		gbc_lblStartAdcMode.anchor = GridBagConstraints.EAST;
		gbc_lblStartAdcMode.insets = new Insets(0, 0, 5, 5);
		gbc_lblStartAdcMode.gridx = 0;
		gbc_lblStartAdcMode.gridy = 2;
		add(lblStartAdcMode, gbc_lblStartAdcMode);
		
		startADCModeComboBox = new JComboBox<LTR11StartADCMode>(new DefaultComboBoxModel<LTR11StartADCMode>(LTR11StartADCMode.values()));
		GridBagConstraints gbc_startADCModeComboBox = new GridBagConstraints();
		gbc_startADCModeComboBox.gridwidth = 2;
		gbc_startADCModeComboBox.insets = new Insets(0, 0, 5, 0);
		gbc_startADCModeComboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_startADCModeComboBox.gridx = 1;
		gbc_startADCModeComboBox.gridy = 2;
		add(startADCModeComboBox, gbc_startADCModeComboBox);
		
		JLabel lblInputMode = new JLabel("Input mode:");
		GridBagConstraints gbc_lblInputMode = new GridBagConstraints();
		gbc_lblInputMode.anchor = GridBagConstraints.EAST;
		gbc_lblInputMode.insets = new Insets(0, 0, 5, 5);
		gbc_lblInputMode.gridx = 0;
		gbc_lblInputMode.gridy = 3;
		add(lblInputMode, gbc_lblInputMode);
		
		inputModeComboBox = new JComboBox<LTR11InputMode>(new DefaultComboBoxModel<LTR11InputMode>(LTR11InputMode.values()));
		GridBagConstraints gbc_inputModeComboBox = new GridBagConstraints();
		gbc_inputModeComboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_inputModeComboBox.gridwidth = 2;
		gbc_inputModeComboBox.insets = new Insets(0, 0, 5, 0);
		gbc_inputModeComboBox.gridx = 1;
		gbc_inputModeComboBox.gridy = 3;
		add(inputModeComboBox, gbc_inputModeComboBox);
		
		JLabel lblPointsCount = new JLabel("Points count:");
		GridBagConstraints gbc_lblPointsCount = new GridBagConstraints();
		gbc_lblPointsCount.anchor = GridBagConstraints.EAST;
		gbc_lblPointsCount.insets = new Insets(0, 0, 5, 5);
		gbc_lblPointsCount.gridx = 0;
		gbc_lblPointsCount.gridy = 4;
		add(lblPointsCount, gbc_lblPointsCount);
		
		pointsCountSpinner = new JSpinner();
		pointsCountSpinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				pointsCountSlider.setValue((Integer)((JSpinner)e.getSource()).getValue());
			}
		});
		pointsCountSpinner.setModel(new SpinnerNumberModel(100, 1, 400, 1));
		GridBagConstraints gbc_pointsCountSpinner = new GridBagConstraints();
		gbc_pointsCountSpinner.fill = GridBagConstraints.HORIZONTAL;
		gbc_pointsCountSpinner.insets = new Insets(0, 0, 5, 5);
		gbc_pointsCountSpinner.gridx = 1;
		gbc_pointsCountSpinner.gridy = 4;
		add(pointsCountSpinner, gbc_pointsCountSpinner);
		
		pointsCountSlider = new JSlider();
		pointsCountSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				pointsCountSpinner.setValue(((JSlider)e.getSource()).getValue());
			}
		});
		pointsCountSlider.setValue(100);
		pointsCountSlider.setMinimum(1);
		pointsCountSlider.setMaximum(400);
		GridBagConstraints gbc_pointsCountSlider = new GridBagConstraints();
		gbc_pointsCountSlider.fill = GridBagConstraints.HORIZONTAL;
		gbc_pointsCountSlider.insets = new Insets(0, 0, 5, 0);
		gbc_pointsCountSlider.gridx = 2;
		gbc_pointsCountSlider.gridy = 4;
		add(pointsCountSlider, gbc_pointsCountSlider);
		
		JPanel panel = new JPanel();
		panel.setBorder(new LineBorder(new Color(0, 0, 0), 2, true));
		GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.anchor = GridBagConstraints.NORTH;
		gbc_panel.gridwidth = 3;
		gbc_panel.fill = GridBagConstraints.HORIZONTAL;
		gbc_panel.gridx = 0;
		gbc_panel.gridy = 5;
		add(panel, gbc_panel);
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = new int[]{0, 0, 0, 0, 0};
		gbl_panel.rowHeights = new int[]{0, 0, 0, 0, 0};
		gbl_panel.columnWeights = new double[]{0.0, 0.0, 1.0, 1.0, Double.MIN_VALUE};
		gbl_panel.rowWeights = new double[]{1.0, 1.0, 1.0, 0.0, Double.MIN_VALUE};
		panel.setLayout(gbl_panel);
		
		JLabel lblNewLabel = new JLabel("Phisycal channel number:");
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.insets = new Insets(5, 0, 5, 5);
		gbc_lblNewLabel.gridx = 0;
		gbc_lblNewLabel.gridy = 0;
		panel.add(lblNewLabel, gbc_lblNewLabel);
		
		channelSpinner = new JSpinner();
		GridBagConstraints gbc_channelSpinner = new GridBagConstraints();
		gbc_channelSpinner.fill = GridBagConstraints.HORIZONTAL;
		gbc_channelSpinner.insets = new Insets(5, 0, 5, 5);
		gbc_channelSpinner.gridx = 1;
		gbc_channelSpinner.gridy = 0;
		panel.add(channelSpinner, gbc_channelSpinner);
		channelSpinner.setModel(new SpinnerNumberModel(1, 1, 32, 1));
		
		JLabel lblChannels = new JLabel("Channels:");
		GridBagConstraints gbc_lblChannels = new GridBagConstraints();
		gbc_lblChannels.gridwidth = 2;
		gbc_lblChannels.insets = new Insets(5, 0, 5, 5);
		gbc_lblChannels.gridx = 2;
		gbc_lblChannels.gridy = 0;
		panel.add(lblChannels, gbc_lblChannels);
		
		JLabel lblNewLabel_1 = new JLabel("Channel mode:");
		GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
		gbc_lblNewLabel_1.anchor = GridBagConstraints.EAST;
		gbc_lblNewLabel_1.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel_1.gridx = 0;
		gbc_lblNewLabel_1.gridy = 1;
		panel.add(lblNewLabel_1, gbc_lblNewLabel_1);
		
		channelModeComboBox = new JComboBox<LTR11VirtualChannelsMode>(new DefaultComboBoxModel<LTR11VirtualChannelsMode>(LTR11VirtualChannelsMode.values()));
		GridBagConstraints gbc_channelModeComboBox = new GridBagConstraints();
		gbc_channelModeComboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_channelModeComboBox.insets = new Insets(0, 0, 5, 5);
		gbc_channelModeComboBox.gridx = 1;
		gbc_channelModeComboBox.gridy = 1;
		panel.add(channelModeComboBox, gbc_channelModeComboBox);
		
		JScrollPane scrollPane = new JScrollPane();
		GridBagConstraints gbc_scrollPane = new GridBagConstraints();
		gbc_scrollPane.gridwidth = 2;
		gbc_scrollPane.insets = new Insets(0, 0, 5, 5);
		gbc_scrollPane.fill = GridBagConstraints.BOTH;
		gbc_scrollPane.gridheight = 2;
		gbc_scrollPane.gridx = 2;
		gbc_scrollPane.gridy = 1;
		panel.add(scrollPane, gbc_scrollPane);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		
		listModel = new DefaultListModel<LTR11Channel>();
		final JList<LTR11Channel> channelsList = new JList<LTR11Channel>(listModel);
		scrollPane.setViewportView(channelsList);
		
		JLabel lblNewLabel_2 = new JLabel("Channel scale:");
		GridBagConstraints gbc_lblNewLabel_2 = new GridBagConstraints();
		gbc_lblNewLabel_2.anchor = GridBagConstraints.EAST;
		gbc_lblNewLabel_2.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel_2.gridx = 0;
		gbc_lblNewLabel_2.gridy = 2;
		panel.add(lblNewLabel_2, gbc_lblNewLabel_2);
		
		channelScaleComboBox = new JComboBox<LTR11Scale>(new DefaultComboBoxModel<LTR11Scale>(LTR11Scale.values()));
		GridBagConstraints gbc_channelScaleComboBox = new GridBagConstraints();
		gbc_channelScaleComboBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_channelScaleComboBox.insets = new Insets(0, 0, 5, 5);
		gbc_channelScaleComboBox.gridx = 1;
		gbc_channelScaleComboBox.gridy = 2;
		panel.add(channelScaleComboBox, gbc_channelScaleComboBox);
		
		btnAddChannel = new JButton("Add channel");
		btnAddChannel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				LTR11Channel channel = new LTR11Channel();
				channel.setPhysicalChannelNo((Integer)channelSpinner.getValue());
				channel.setChannelMode(channelModeComboBox.getItemAt(channelModeComboBox.getSelectedIndex()));
				channel.setChannelScale(channelScaleComboBox.getItemAt(channelScaleComboBox.getSelectedIndex()));
				listModel.addElement(channel);
			}
		});
		GridBagConstraints gbc_btnAddChannel = new GridBagConstraints();
		gbc_btnAddChannel.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnAddChannel.insets = new Insets(0, 0, 5, 5);
		gbc_btnAddChannel.gridx = 2;
		gbc_btnAddChannel.gridy = 3;
		panel.add(btnAddChannel, gbc_btnAddChannel);
		
		btnRemoveChannel = new JButton("Remove channel");
		btnRemoveChannel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (channelsList.getSelectedIndex() != -1) {
					listModel.remove(channelsList.getSelectedIndex());
				}
			}
		});
		GridBagConstraints gbc_btnRemoveChannel = new GridBagConstraints();
		gbc_btnRemoveChannel.insets = new Insets(0, 0, 5, 0);
		gbc_btnRemoveChannel.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnRemoveChannel.gridx = 3;
		gbc_btnRemoveChannel.gridy = 3;
		panel.add(btnRemoveChannel, gbc_btnRemoveChannel);

	}
	
	private List<Short> filteredItems() {
		LinkedList<Short> ret = new LinkedList<Short>();
		LinkedList<Short> modules = ((LTRCrate)cratesSNComboBox.getSelectedItem()).getModules();
		for(short i = 0; i < modules.size(); i++) {
			if (modules.get(i) == LTRAPIConstants.MID_LTR11) {
				ret.add(i);
			}
		}
		return ret;
	}
	
	public void addCrateItemChangeListener(ItemListener itemListener) {
		cratesSNComboBox.addItemListener(itemListener);
	}
	
	public void addModuleChangeItemListener(ItemListener itemListener) {
		slotNoComboBox.addItemListener(itemListener);
	}
	
	public void addStartModeItemChangeListener(ItemListener itemListener) {
		startADCModeComboBox.addItemListener(itemListener);
	}
	
	public void addInputeModeChangeListener(ItemListener itemListener) {
		inputModeComboBox.addItemListener(itemListener);
	}
	
	public void addAddChannelActionListener(ActionListener actionListener) {
		btnAddChannel.addActionListener(actionListener);
	}
	
	public void addRemoveChannelActionListener(ActionListener actionListener) {
		btnRemoveChannel.addActionListener(actionListener);
	}
}
